<script setup lang='ts'>
import { appRef } from '@/models/app.ref';
import { FileItem, Message } from '@arco-design/web-vue';
import { onMounted, ref } from 'vue';
import Sider from '@/components/chat/Sider.vue'
import Interactive from '@/components/chat/Interactive.vue'
import Explanation from '@/components/Explanation.vue'
import PreviewFile from '@/components/previewFile/index.vue'
import { fileService } from '@/services/file.service';
import { ChatFileMenuInfo, accept } from '@/models/chat-file';
import { SiderMenuEnum } from '@/models/@types';
import { deduplication, getUuid } from '@/utils/common.methods';
import { hope } from '@/tools/hope/@types/hope';
import { AssetInfo } from '@/models/asset';
const menus = ref([]);
const currMenu = ref({} as ChatFileMenuInfo);
const isMobile = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);
const loading = ref(false);
onMounted(() => {
  init();
})

async function init(): Promise<void> {
  loading.value = true;
  menus.value = await appRef.chatFile.menus();
  currMenu.value = appRef.chatFile?.currMenu;
  files.value = [];
  asset.value = {} as AssetInfo;
  loading.value = false;
}


async function onAdd(e: { type: SiderMenuEnum, parent?: string }): Promise<void> {
  const { type, parent } = e
  await appRef.chatFile.add(type, parent);
  init();
}

async function onItem(uid: string): Promise<void> {
  console.log('onItem', uid);
  await appRef.chatFile.setCurrKey(uid);
  init();
}
async function onEdit(param: { uid: string, label: string }): Promise<void> {
  const { uid, label } = param;
  await appRef.chatFile.edit(uid, label);
}

async function onRemove(uid: string): Promise<void> {
  await appRef.chatFile.remove(uid);
  init();
}

async function onUpdate(enmus: ChatFileMenuInfo[]): Promise<void> {
  await appRef.chatFile.update(enmus)
  init();
}

const isUploadLading = ref(false);
const validate = (file: File): boolean => {
  const { type, size } = file;
  const fileName = file.name;
  const fileExt = fileName.slice(fileName.lastIndexOf(".")).toLowerCase(); // 获取文件扩展名
  if (!(accept.split(',').includes(fileExt))) {
    Message.error('只能上传' + accept + ' 格式的文件');
    return false;
  }
  if (size > 1024 * 1024 * 30) {
    Message.error('只能上传小于 30M 的文件');
    return false;
  }
  return true;
}
const limit = 3;
function uploadChange(): void {
  files.value = deduplication<FileItem>(files.value, 'name')?.filter(val => validate(val.file));
  if (files.value?.length > limit) {
    files.value = files.value?.slice(0, limit);
    Message.warning("最多限制" + limit + '个文件')
  }
}

const files = ref([] as FileItem[]);
function onUpload(e): void {
  console.log(files.value);
  isUploadLading.value = true;
  e.stopPropagation();
  hope.upload({
    files: files.value?.map(val => val.file),
    success: async res => {
      isUploadLading.value = false;
      await appRef.chatFile.updatedFile(currMenu.value.uid, res);
      isExpire.value = false;
      isSend.value = false;
    },
    complete: () => {
      isUploadLading.value = false;
      isExpire.value = false;
      isSend.value = false;
    }
  })
}

const controllerKey = getUuid();
const textarea = ref('');
const isSend = ref(false);
const isExpire = ref(false);  // 文件过期
const chunk = ref('');

function sendMessage(value: string, quote?: string): void {
  chunk.value = '';
  isSend.value = true;
  textarea.value = '';
  fileService.send(controllerKey, currMenu.value.assets, value, currMenu.value.modeluid, onChunk, () => {
    isSend.value = false;
  }, quote);
}

function onChunk(text: string): void {
  chunk.value += text;
}

function onRefresh(quote: string): void {
  sendMessage('', quote)
}

const isPreview = ref(true); // 文件预览
const previewId = ref(''); // 文件预览
const asset = ref({} as AssetInfo);
function onPreview(): void {
  asset.value = currMenu.value?.assets?.find(val => val.id === previewId.value);
  isPreview.value = true;
}
function onClosePreview(): void {
  asset.value = {} as AssetInfo;
  previewId.value = '';
  isPreview.value = false;
}

</script>
<template>
  <div class="index">
    <a-layout style="height: 100%;">

      <a-layout>
        <div class="main flex" v-if="currMenu?.uid">
          <div class="main flex" v-if="currMenu?.assets?.length">
            <div class="main-content flex-c" v-if="!loading">
              <Interactive :sessions="currMenu.sessions" v-model:isSend="isSend" :chunk="chunk" :isrefresh="true"
                @send="sendMessage" @refresh="onRefresh"
                @remove="async ($event) => await appRef.chatFile.removeMenuAnswer($event)"
                @editTextarea="textarea = $event" :isStopSend="false">

                <template #select-model>
                  <a-select style="width: 200px;margin-right: 5px;" v-model="currMenu.modeluid" placeholder="请选择模型">
                    <a-option v-for="item in appRef.chatFile._models" :value="item.key" :label="item.value"></a-option>
                  </a-select>
                </template>
                <template #button-bar>
                  <a-select placeholder="请选择文件预览" @change="onPreview" v-model="previewId">
                    <a-option v-for="item in currMenu.assets" :value="item.id" :label="item.name"></a-option>
                  </a-select>
                </template>
              </Interactive>
              <div class="text flex">
                <a-textarea class="textarea" v-model="textarea" :auto-size="{ minRows: 2, maxRows: 7 }"
                  placeholder="粘贴或输入你的需求，如: 请帮我看看文章有没有问题，附上文章的内容 （Ctrl + Enter = 发送，Enter = 换行）"
                  @keydown.ctrl.enter="sendMessage(textarea)" />
                <a-button class="send" type="primary" :disabled="!textarea" @click.stop="sendMessage(textarea)"
                  :loading="isSend">
                  <template #icon> <icon-send /> </template>
                  <template #default>发送</template>
                </a-button>
              </div>
            </div>
            <PreviewFile v-if="!isMobile && asset?.url && isPreview" class="previewfile" :asset="asset"
              @close="onClosePreview">
            </PreviewFile>
          </div>

          <div class="upload" v-else>
            <a-upload :auto-upload="false" v-model:file-list="files" :accept="accept" multiple @change="uploadChange">
              <template #upload-button>
                <a-space>
                  <a-button v-if="files?.length" :disabled="files?.length > 2" :loading="isUploadLading">继续选择</a-button>
                  <div class="upload-card flex-c" v-else>
                    <div> <span style="color: #3370FF"> 点击</span>或拖拽文件到此处上传 </div>
                    <div class="tips"> 支持 {{ accept }} </div>
                  </div>
                  <a-button type="primary" @click="onUpload" v-if="files?.length"
                    :loading="isUploadLading">确认上传</a-button>
                </a-space>
              </template>
            </a-upload>
          </div>
        </div>
        <Explanation v-else />
      </a-layout>
      <Sider :menus="menus" :default-uid="currMenu?.uid" @add="onAdd"
        @clear="async () => { await appRef.chatFile.clear(); init() }" @click-item="onItem"
        @edit="($event) => { onEdit($event); init() }" @remove="($event) => { onRemove($event) }"
        @update="($event) => onUpdate($event)" />
    </a-layout>
  </div>
</template>
<style lang='scss' scoped>
.index {
  height: 100%;

  .main {
    width: 100%;
    height: 100%;
    overflow: hidden;
    margin: 0 auto;
    justify-content: center;

    .previewFile {
      height: 30px;
      text-align: right;
      padding-right: 20px;
      justify-content: center;

    }

    .upload {
      width: 100%;
      max-width: 500px;
    }
  }

  .main-content {
    max-width: 1270px;
    height: 100%;
    overflow: hidden;
    margin: 0 auto;
    justify-content: center;
    flex: 1;
  }

  .previewfile {
    height: 100%;
    overflow: hidden;
    flex: 1;
  }

  .text {
    width: 100%;
    padding-bottom: 17px;
    position: relative;

    .textarea {
      padding-right: 100px;
      height: 100%;
    }

    .textarea {
      padding-right: 100px;
    }

    .send {
      position: absolute;
      right: 10px;
      bottom: 27px;
      // margin-left: 10px;
    }
  }

  .upload-card {
    background-color: var(--color-fill-2);
    color: var(--color-text-1);
    border: 1px dashed var(--color-fill-4);
    padding: 40px;
    border-radius: 4px;
    justify-content: center;
    line-height: 24px;
    text-align: center;
  }
}
</style>

<style lang="scss">
.main {
  .arco-split-pane {
    height: 100%;
  }
}
</style>
